package Threads;

public class ConsumerAndProductor {
    public static void main(String[] args) {
        Manager manager = new Manager();

        Thread productor = new Thread(new Productor(manager));
        Thread c1 = new Thread(new Consumer(manager));
        Thread c2 = new Thread(new Consumer(manager));

        productor.setName("Productor");
        c1.setName("Consumer1");
        c2.setName("Consumer2");

        productor.start();
        c1.start();
        c2.start();

    }
}

class Manager {

    private int count = 0;
    private static final int MAX_COUNT = 10;

    public synchronized void produce() {
        if (count < MAX_COUNT) {
            count++;
            System.out.println(Thread.currentThread().getName() + " produce No. " + count + " product");
            notifyAll();
        } else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void consume() {
        if (count > 0) {
            System.out.println(Thread.currentThread().getName() + " consume No. " + count + " product");
            count--;
            notifyAll();
        } else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Consumer implements Runnable {

    private Manager manager;

    public Consumer(Manager manager) {
        this.manager = manager;
    }

    public void run() {
        while (true) {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            manager.consume();
        }
    }
}

class Productor implements Runnable {

    private Manager manager;

    public Productor(Manager manager) {
        this.manager = manager;
    }

    public void run() {
        while (true) {
            try {
                Thread.sleep(90);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            manager.produce();
        }
    }
}
